package com.jilefojing.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jilefojing.beans.data.enums.ResponseEnum;
import com.jilefojing.beans.enums.ItemTypeEnumForSource;
import com.jilefojing.beans.enums.StatusEnumForPublish;
import com.jilefojing.beans.exception.UserContextException;
import com.jilefojing.beans.pojos.Favorite;
import com.jilefojing.beans.pojos.RFavoriteSource;
import com.jilefojing.beans.pojos.Statistics;
import com.jilefojing.beans.pojos.User;
import com.jilefojing.beans.pojos.enhanced.EnhancedRFavoriteSource;
import com.jilefojing.beans.pojos.enhanced.base.BaseEnhanced;
import com.jilefojing.beans.query.RFavoriteSourceQuery;
import com.jilefojing.beans.vo.Pagination;
import com.jilefojing.context.beans.vo.UserContext;
import com.jilefojing.dao.IEVideoDao;
import com.jilefojing.dao.IFavoriteDao;
import com.jilefojing.dao.IRFavoriteSourceDao;
import com.jilefojing.dao.IStatisticsDao;
import com.jilefojing.service.IRFavoriteSourceService;
import com.jilefojing.service.ISourceService;
import com.jilefojing.service.IStatisticsService;
import com.jilefojing.service.base.impl.BaseService;
import com.jilefojing.util.Detect;

/**
 * 
 * @author 作者 jgshun
 * @date 创建时间 2016年07月23日 02时21分15秒
 */
@Service
public class RFavoriteSourceService extends BaseService<RFavoriteSource> implements IRFavoriteSourceService {
	@Autowired
	private IRFavoriteSourceDao rFavoriteSourceDao;
	@Autowired
	private IEVideoDao eVideoDao;
	@Autowired
	private IFavoriteDao favoriteDao;
	@Autowired
	private IStatisticsDao statisticsDao;

	@Autowired
	private IStatisticsService statisticsService;
	@Autowired
	private ISourceService sourceService;

	@Override
	public RFavoriteSource add(RFavoriteSource rFavoriteSource, UserContext userContext) throws UserContextException {
		if (rFavoriteSource.getItemId() == null || rFavoriteSource.getItemType() == null) {
			throw new UserContextException(ResponseEnum.LACK_OF_NECESSARY_PARAMETERS);
		}
		ItemTypeEnumForSource itemType = ItemTypeEnumForSource.getItemTypeEnumByCode(rFavoriteSource.getItemType());
		if (itemType == null) {
			throw new UserContextException(ResponseEnum.SOURCE_TYPE_UNSUPPORT);
		}

		BaseEnhanced enhancedItem = sourceService.getEnhancedItem(itemType, rFavoriteSource.getItemId(), userContext);
		if (enhancedItem == null) {
			throw new UserContextException(ResponseEnum.SOURCE_NOT_EXIST);
		} else if (enhancedItem.get("getStatus") == null || enhancedItem.get("getStatus") != StatusEnumForPublish.ALREADY_RELEASED) {
			throw new UserContextException(ResponseEnum.SOURCE_INVALID);
		}

		User user = new User();
		user.setId(userContext.getUserId());

		RFavoriteSource dbRecord = rFavoriteSourceDao.getByItemForUser(ItemTypeEnumForSource.getItemTypeEnumByCode(rFavoriteSource.getItemType()), rFavoriteSource.getItemId(), user);
		if (dbRecord != null) {
			throw new UserContextException("已在[" + favoriteDao.getById(dbRecord.getFavoriteId()).getName() + "]中收藏");
		}
		Date now = new Date();

		Favorite favorite = null;
		if (rFavoriteSource.getFavoriteId() == null || rFavoriteSource.getFavoriteId() < 1) {
			// 创建类型对应的收藏夹
			String name = itemType.getMsg();
			favorite = favoriteDao.getByNameForUser(name, user);
			if (favorite == null) {
				favorite = new Favorite();
				favorite.setCreateTime(now);
				favorite.setUpdateTime(now);
				favorite.setUserId(userContext.getUserId());
				favorite.setName(name);
				favorite = favoriteDao.saveSelective(favorite);
			}
		} else {
			favorite = favoriteDao.getById(rFavoriteSource.getFavoriteId());
			if (favorite == null) {
				throw new UserContextException(ResponseEnum.FAVORITE_NOT_EXIST);
			} else if (favorite.getUserId() != userContext.getUserId()) {
				throw new UserContextException(ResponseEnum.UNAUTHORIZED_ACCESS);
			}
		}

		long saveItemId = enhancedItem.getDynamicId();
		if (enhancedItem.getBoolean("getEntity")) {
			Object parentObj = enhancedItem.get("getEnhancedParent");
			if (parentObj != null && ((BaseEnhanced) parentObj).getDynamicId() > 0) {
				saveItemId = ((BaseEnhanced) parentObj).getDynamicId();
			}
		}

		RFavoriteSource record = new RFavoriteSource();
		record.setItemId(saveItemId);
		record.setItemType(rFavoriteSource.getItemType());
		record.setUserId(userContext.getUserId());
		record.setCreateTime(now);
		record.setFavoriteId(favorite.getId());

		record = rFavoriteSourceDao.saveSelective(record);

		statisticsService.updateCount(itemType, record.getItemId(), Statistics.COLUMN_COUNT_FAVORITE, true, 1, userContext);

		return record;
	}

	@Override
	public void cancleById(long id, UserContext userContext) throws UserContextException {
		RFavoriteSource rFavoriteSource = rFavoriteSourceDao.getById(id);
		if (rFavoriteSource != null) {
			if (rFavoriteSource.getUserId() != userContext.getUserId()) {
				throw new UserContextException(ResponseEnum.UNAUTHORIZED_ACCESS);
			}
			rFavoriteSourceDao.deleteById(id);
		}
	}

	@Override
	public void cancleByItem(RFavoriteSource rFavoriteSource, UserContext userContext) throws UserContextException {
		if (rFavoriteSource.getItemId() == null || rFavoriteSource.getItemType() == null) {
			throw new UserContextException(ResponseEnum.LACK_OF_NECESSARY_PARAMETERS);
		}

		User user = new User();
		user.setId(userContext.getUserId());

		RFavoriteSource dbRecord = rFavoriteSourceDao.getByItemForUser(ItemTypeEnumForSource.getItemTypeEnumByCode(rFavoriteSource.getItemType()), rFavoriteSource.getItemId(), user);
		if (dbRecord != null) {
			rFavoriteSourceDao.deleteById(dbRecord.getId());
			statisticsService.updateCount(ItemTypeEnumForSource.getItemTypeEnumByCode(dbRecord.getItemType()), dbRecord.getItemId(), Statistics.COLUMN_COUNT_FAVORITE, false, 1, userContext);
		}

	}

	@Override
	public EnhancedRFavoriteSource getEnhancedRFavoriteSourceByItemForUser(ItemTypeEnumForSource itemType, long itemId, UserContext userContext) {
		List<EnhancedRFavoriteSource> enhancedRFavoriteSources = this.getEnhancedRFavoriteSourcesByItemsForUser(itemType, Arrays.asList(new Long[] { itemId }), userContext);
		if (!Detect.notEmpty(enhancedRFavoriteSources)) {
			return null;
		}
		return enhancedRFavoriteSources.get(0);
	}

	@Override
	public List<EnhancedRFavoriteSource> getEnhancedRFavoriteSourcesByItemsForUser(ItemTypeEnumForSource itemType, List<Long> itemIds, UserContext userContext) {
		RFavoriteSourceQuery rFavoriteSourceQuery = new RFavoriteSourceQuery();
		rFavoriteSourceQuery.setItemIds(itemIds);
		rFavoriteSourceQuery.setItemTypes(Arrays.asList(new ItemTypeEnumForSource[] { itemType }));
		rFavoriteSourceQuery.setUserIds(Arrays.asList(new Long[] { userContext.getUserId() }));

		Pagination<EnhancedRFavoriteSource> pagination = new Pagination<EnhancedRFavoriteSource>(1, Integer.MAX_VALUE, false);

		return this.getPagination(rFavoriteSourceQuery, pagination, userContext).getItems();
	}

	@Override
	public Pagination<EnhancedRFavoriteSource> getPagination(RFavoriteSourceQuery rFavoriteSourceQuery, Pagination<EnhancedRFavoriteSource> pagination, UserContext userContext) {

		@SuppressWarnings("unchecked")
		Pagination<RFavoriteSource> rFavoriteSourcePagination = rFavoriteSourceDao.getPagination(rFavoriteSourceQuery, pagination.copy());
		pagination.setCount(rFavoriteSourcePagination.getCount());
		if (!Detect.notEmpty(rFavoriteSourcePagination.getItems())) {
			return pagination;
		}
		List<EnhancedRFavoriteSource> enhancedRFavoriteSources = this.conventRFavoriteSources2EnhancedRFavoriteSources(rFavoriteSourcePagination.getItems());
		pagination.setItems(enhancedRFavoriteSources);
		return pagination;
	}

	@Override
	public List<EnhancedRFavoriteSource> conventRFavoriteSources2EnhancedRFavoriteSources(List<RFavoriteSource> rFavoriteSources) {
		List<EnhancedRFavoriteSource> enhancedRFavoriteSources = new ArrayList<EnhancedRFavoriteSource>();
		for (RFavoriteSource _RFavoriteSource : rFavoriteSources) {
			enhancedRFavoriteSources.add(new EnhancedRFavoriteSource(_RFavoriteSource));
		}
		return enhancedRFavoriteSources;
	}
}
